package com.jxw.cloudpen.web.microsoft.stremspeed;

import com.alibaba.fastjson.JSONObject;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.framing.Framedata;
import org.java_websocket.framing.FramedataImpl1;
import org.java_websocket.handshake.ServerHandshake;

import javax.sound.sampled.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class WebSocketToyClientAI extends org.java_websocket.client.WebSocketClient {

    static Boolean isStop = false;
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    static Boolean isImgStop = true;
    static String token = "login_jxwdevice29953097khkkfted6hulddap80vbkgkm5c7mo30p";

    //bench
//    static String token = "login_jxwdevice21383326xsw4ldtsqo2eqbiddyt9s1e6dbbqehfi";
    static long startTime = System.currentTimeMillis();

    static Boolean isBrek = false;
    static int ttsNum = 0;

    public WebSocketToyClientAI(URI serverUri) {
        super(serverUri);
    }

    public WebSocketToyClientAI(URI serverUri, Draft protocolDraft, Map<String, String> httpHeaders, int connectTimeout) {
        super(serverUri, protocolDraft, httpHeaders, connectTimeout);
    }

    /**
     * 启动定时发送ping的定时器
     */

    private Timer pingTimer;

//    @Override
//    public void onWebsocketPong(WebSocket conn, Framedata f) {
        public void onWebsocketPong() {

        if (pingTimer != null) {
            pingTimer.cancel();
        }
        pingTimer = new Timer("WebSocket-Ping-Timer", true);
        // 定时发送ping，延迟0秒开始，每PING_INTERVAL秒执行一次
        pingTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if (isOpen()) { // 连接打开状态才发送ping
                    // 当ping生效后，会返回一个Pong信息，这里接收到Pong后等待一秒后再发送一个ping
//                    System.out.println("接收到ping返回的pong回复");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    ByteBuffer pingData = ByteBuffer.wrap(("PING").getBytes());
                    FramedataImpl1 framedataImpl1 = FramedataImpl1.get(Framedata.Opcode.TEXT);
                    framedataImpl1.setPayload(pingData);
                    sendFrame(framedataImpl1);
                    // 发送ping后，检查是否在超时时间内收到pong
                }
            }
        }, 0, 1 * 1000L);



//        // 当ping生效后，会返回一个Pong信息，这里接收到Pong后等待一秒后再发送一个ping
//        System.out.println("接收到ping返回的pong回复");
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        ByteBuffer pingData = ByteBuffer.wrap(("ping-" + System.currentTimeMillis()).getBytes());
//        FramedataImpl1 framedataImpl1 = FramedataImpl1.get(Framedata.Opcode.TEXT);
//        framedataImpl1.setPayload(pingData);
//        this.sendFrame(framedataImpl1);
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        System.out.println("Connected");
//        onWebsocketPong();
//        this.send("Hello Server!"); // 发送消息到服务器
//        for(;;){
//            this.send(ByteObjUtil.objToBytes("aaaa"));
//            this.send("aaaa");
//            try {
//                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
        AiSocketChatDTO request = new AiSocketChatDTO();
        request.setTypeState("start");
//        request.setClientId("f544f5209e7d4f59a82ba3a780736faf1");
        this.send(JSONObject.toJSONString(request));
        System.out.println("ddddddd");

        startTime = System.currentTimeMillis();
//        while(true){
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            this.send(JSONObject.toJSONString(request));
//        }
//        try {
//            executeMusic();
//        } catch (LineUnavailableException e) {
//
//        }

    }


    private static TargetDataLine targetDataLine;

    private static volatile BlockingQueue<byte[]> sharedQueue = new LinkedBlockingQueue<byte[]>();


    public StreamData executeMusic() throws LineUnavailableException {


        // SampleRate:16000Hz, SampleSizeInBits: 16, Number of channels: 1, Signed: true,
        // bigEndian: false
        AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
        DataLine.Info targetInfo =
                new DataLine.Info(
                        TargetDataLine.class,
                        audioFormat); // Set the system information to read from the microphone audio
        // stream

        if (!AudioSystem.isLineSupported(targetInfo)) {
            System.out.println("Microphone not supported");
            System.exit(0);
        }
        // Target data line captures the audio stream the microphone produces.
        targetDataLine = (TargetDataLine) AudioSystem.getLine(targetInfo);
        targetDataLine.open(audioFormat);

//        StreamData result = new StreamData();
// Microphone Input buffering
        class MicBuffer implements Runnable {

            @Override
            public void run() {
                System.out.println("Start speaking...Press Ctrl-C to stop");
                targetDataLine.start();
                byte[] data = new byte[6400];
                while (targetDataLine.isOpen()) {
                    try {
                        int numBytesRead = targetDataLine.read(data, 0, data.length);
                        if ((numBytesRead <= 0) && (targetDataLine.isOpen())) {
                            continue;
                        }
                        //组装数据
                        sharedQueue.put(data.clone());
                    } catch (InterruptedException e) {
                        System.out.println("Microphone input buffering interrupted : " + e.getMessage());
                    }
                }
            }
        }

        // Creating microphone input buffer thread
        MicBuffer micrunnable = new MicBuffer();
        Thread micThread = new Thread(micrunnable);
        micThread.start();
        try {
            if (!AudioSystem.isLineSupported(targetInfo)) {
                System.out.println("Microphone not supported");
                System.exit(0);
            }
            while (true) {
                byte[] bytes = sharedQueue.take();
                if (bytes != null && bytes.length > 0) {
//                    result = new StreamData();
//                    result.setClientId(clientId);
//                    result.setData(bytes);
//                    result.setType(2);
//                    result.setToken(token);

                    AiSocketChatDTO result = new AiSocketChatDTO();
                    result.setConversationId(clientId);
                    result.setTypeState("input");
//                    result.setImgUrl("https://tospub-test.zhinengtongbu.com/tmp/tts/20250704/尊敬.jpg");
                    result.setQuery(bytes);
//                    if (System.currentTimeMillis() - startTime > 18000 && !isBrek) {
//                        AiSocketChatDTO result2 = new AiSocketChatDTO();
//                        result2.setConversationId(clientId);
//                        isBrek = true;
//                        result2.setIsBreak(isBrek);
//                        this.send(JSONObject.toJSONString(result2));
//                    }
//                bootstrap.channel.writeAndFlush(result);
//                    bootstrap.channel.writeAndFlush(ByteObjUtil.objToBytes(result));
//                    this.send(ByteObjUtil.objToBytes(result));
                    if (System.currentTimeMillis() - startTime > 3000) {

                        if(!isStop){
                            AiSocketChatDTO result2 = new AiSocketChatDTO();
                            result2.setConversationId(clientId);
                            result2.setTypeState("end");
                            this.send(JSONObject.toJSONString(result2));


                        }
                        isStop = true;
                    }


//                    if (System.currentTimeMillis() - startTime > 12000 && isImgStop) {
//
//                        AiSocketChatDTO request = new AiSocketChatDTO();
//                        request.setImgUrl("https://tospub-test.zhinengtongbu.com/tmp/tts/20250704/尊敬.jpg");
//                        this.send(JSONObject.toJSONString(request));
//
//                        isImgStop=false;
//                    }

                    if (!isStop) {
//                        MicrophoneRecorderUtil recorder = new MicrophoneRecorderUtil();
//                        result = new StreamData();
//                        result.setClientId(clientId);
//                        result.setType(2);
//                        result.setToken(token);
//                        recorder.startRecordingV2(this, result);


//                        System.out.println("result is {}"+JSONObject.toJSONString(result));
                        this.send(JSONObject.toJSONString(result));
//                         System.out.println("result is {}"+JSONObject.toJSONString(result));
                    }
//                    else {
//                        isStop = false;
//                    }


                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);
        }

//        try {
//            Thread.sleep(10000);
//            isStop = true;
//
//            AiSocketChatDTO result = new AiSocketChatDTO();
//            result.setConversationId(clientId);
//            result.setTypeState("end");
//            this.send(JSONObject.toJSONString(result));
//
//
//            micThread.stop();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return null;
    }

    static Long message_pre_l =0L;
    static Long tts_pre_l =0L;
    static boolean pan = true;
    static Long clientId = 0L;

    static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    @Override
    public void onMessage(String message) {
//        System.out.println(String.format("data : %s  Received: %s", simpleDateFormat.format(new Date()), message));

        JSONObject jsonObject = JSONObject.parseObject(message).getJSONObject("data");
        Long clientId2 = jsonObject.getLong("conversationId");

        String event = jsonObject.getString("event");
        if (event.indexOf("tts_") > -1) {
//            if ((++ttsNum) < 5) {
            JSONObject jsonObject1 =  JSONObject.parseObject(message);
                System.out.println(String.format("data : %s  Received: %s", simpleDateFormat.format(new Date()), jsonObject1.getJSONObject("data").getString("event")));
//            System.out.println(String.format("data : %s  Received: %s", simpleDateFormat.format(new Date()), message));
//            }
        } else {
            System.out.println(String.format("data : %s  Received: %s", simpleDateFormat.format(new Date()), message));
        }


        if("message_pre".equals(event)){
            message_pre_l = System.currentTimeMillis();
        }
        if("tts_message".equals(event) && tts_pre_l==0){
            tts_pre_l = System.currentTimeMillis();
        }
        if("tts_message_end".equals(event)){
            System.out.println(String.format("tts 第一帧耗时 : %s  ", (tts_pre_l - message_pre_l)));
        }
        if (pan && "start".equals(event)) {
            startTime = System.currentTimeMillis();
            clientId = clientId2;
            pan = false;
            executorService.submit(() -> {
                try {
                    executeMusic();
                } catch (LineUnavailableException e) {

                }
            });


        }

        //发送图片

//        try {
        //主动挂断
//            executorService.submit(()-> {
//                try {
//                    try {
//                        Thread.sleep(30000L);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    StreamData result = new StreamData();
//                    result.setClientId("f544f5209e7d4f59a82ba3a780736faf");
//                    result.setType(3);
//                    isStop = true;
//                    this.send(JSONObject.toJSONString(result));
//                } catch (Exception e) {
//                    System.out.println("Exception caught: " + e);
//                }
//            });


        //切换语言
//        executorService.submit(() -> {
//            try {
//                try {
//                    Thread.sleep(30000L);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                StreamData result = new StreamData();
//                result.setClientId("f544f5209e7d4f59a82ba3a780736faf");
//                result.setType(4);
//                result.setLanguageCode("en-US");
//                this.send(JSONObject.toJSONString(result));
//            } catch (Exception e) {
//                System.out.println("Exception caught: " + e);
//            }
//        });
//
//
//        try {
//            executeMusic();
//        } catch (LineUnavailableException e) {
//
//        }


    }


    @Override
    public void onMessage(ByteBuffer bytes) {
        System.out.println("Received22: " + bytes);
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        System.out.println("Disconnected");
    }

    @Override
    public void onError(Exception ex) {
        System.err.println("Error: " + ex.getMessage());
    }

    public static void main(String[] args) throws URISyntaxException {
        startTime = System.currentTimeMillis();
//        String url = "ws://gwsdb-sgp-test.xuexizhiwang.com/stream-speech";

//        String url = "ws://gwpad.xuexizhiwang.com/stream-speech";
//        String url = "wss://gw-test.xuexizhiwang.com:443/test";

//        String url = "ws://gw-pre.xuexizhiwang.com/stream-speech";
//        String url = "ws://gw-pre.xuexizhiwang.com/stream-speech";
        String url = "ws://localhost:6601/ai/dialogue/toy";

//        String url = "ws://gw-bench.xuexizhiwang.com/ai/dialogue/mood";

//        String url = "ws://172.26.28.68:6601/ai/stream/asr";
//        String url = "ws://gw-test.xue
//
//
//        xizhiwang.com/ai/stream/asr";
//        String url = "ws://gw-test.xuexizhiwang.com/ai/dialogue/toy";
//        String url = "ws://gw-test.xuexizhiwang.com/ai/dialogue/toy";
//        String url = "ws://172.26.28.68:6601/stream-speech";

        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        Draft draft = new Draft_6455();
//        String url = "ws://localhost:6601/websocket";
        WebSocketToyClientAI client = new WebSocketToyClientAI(new URI(url), draft, headers, 50000); // 替换为你的WebSocket服务器地址和端点


        client.connect();
    }
}
